﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;
using MyClass_StringProcess;
using MyClass_CRC;

namespace WaterMachine2
{
    public partial class WaterMachine : Form
    {
        delegate void UpdateTextEventHandler(byte[] text);//委托，此为重点
        UpdateTextEventHandler updateText;
        
        enum DataGirdViewControls {All_Select, NC, ReadCoeff, WriteCoeff, SaveCoeff, LoadCoeff};
        //IList<int> DataGirdViewBindData = new List<int>();

        private Encoding GB2312 = Encoding.GetEncoding("gb2312");

        //系统初始化
        public WaterMachine()
        {
            InitializeComponent();
            updateText = new UpdateTextEventHandler(UpdateTextBox);//实例化委托对象
            
            Serial_Rate.SelectedIndex = 6;

            Init_COM_Port_List();

            Init_Write_Coeff();

            Serial_Status();
        }

        //窗口关闭提示
        private void WaterMachine_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                DialogResult r = MessageBox.Show("您将关闭程序?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (r != DialogResult.OK)
                {
                    e.Cancel = true;//不关闭窗口
                }
                else
                {
                    Serial1.Close();
                }
            }
        }

        //串口工作状态指示  如果开，则显示关闭串口，绿色，反之显示打开串口，红色
        private void Serial_Status()
        {
            //设置按钮状态
            Serial_OpenPort.Text = Serial1.IsOpen ? "关闭串口" : "打开串口";
            Serial_Open_Flag.ForeColor = Serial1.IsOpen ? Color.Green : Color.Red;
            string text = Serial1.IsOpen ? " 已打开" : " 未打开";
            Label_Serial_Info.Text = Serial_COM.Text + text + Serial_Rate.Text + "bps," + "8,1,None,None";

            //改变控件状态
            bool Control_En = Serial1.IsOpen ? Enabled : !Enabled;
            //读写地址控件状态
            Serial_ReadAddr.Enabled = Control_En;
            Serial_WriteAddr.Enabled = Control_En;
            Serial_Addr.Enabled = Control_En;
            //读写ID 控件状态
            Serial_ReadID.Enabled = Control_En;
            Serial_WriteID.Enabled = Control_En;
            Serial_ID.Enabled = Control_En;
            //低功耗 radio 控件状态
            Serial_CloseMode_LowPower.Enabled = Control_En;
            Serial_OpenMode_LowPower.Enabled = Control_En;
            //打印模式 radio 控件状态
            Serial_CloseMode_Print.Enabled = Control_En;
            Serial_OpenMode_Print.Enabled = Control_En;
            //主动上传模式 radio 控件状态
            Serial_CloseMode_AutoSend.Enabled = Control_En;
            Serial_OpenMode_AutoSend.Enabled = Control_En;
            //时间间隔控件状态
            Serial_Interval.Enabled = Control_En;
            Serial_Write_Interval.Enabled = Control_En;
            //读工作状态控件
            Serial_ReadStatus_Work.Enabled = Control_En;
            
        }

        private void Serial_Open()
        {
            if (Serial1.IsOpen)
            {
                Serial1.Close();
            }
            Serial1 = new SerialPort(Serial_COM.Text);
            Serial1.BaudRate = int.Parse(Serial_Rate.Text);
            Serial1.DataBits = 8;
            Serial1.Encoding = GB2312;
            Serial1.Handshake = Handshake.None;
            Serial1.Parity = Parity.None;
            Serial1.StopBits = StopBits.One;
            //Serial1.ReadTimeout = 500;
            //Serial1.WriteTimeout = 400;

            try
            {
                Serial1.Open();
                
                Serial1.DataReceived += new SerialDataReceivedEventHandler(Com_DataReceived);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Com_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            if (Serial1.IsOpen && Serial1.BytesToRead > 0)
            {
                try
                {
                    System.Threading.Thread.Sleep(100);
                    //开辟接收缓冲区
                    byte[] ReDatas = new byte[Serial1.BytesToRead];

                    Serial1.Read(ReDatas, 0, Serial1.BytesToRead);
                    //实现数据的解码与显示
                    this.Invoke(updateText, ReDatas);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
        // 数据帧校验
        private bool CheckFrame(byte[] buff)
        {
            if (buff.Length < 4)
                return false;

            UInt16 CheckSum = myclass_crc.CRC16(buff, buff.Length);

            if (CheckSum == 0)
                return true ;
            else
                return false;
        }
        //RadioButton 状态更改
        private string RadioButton_LowerPowerModel_Status(byte status)
        {
            if (status == 1)
            {
                Serial_OpenMode_LowPower.Checked = true;
                return "低功耗模式 开启成功";
            }
            else
            {
                Serial_CloseMode_LowPower.Checked = true;
                return "低功耗模式 已关闭";
            }
        }
        private string RadioButton_PrintModel_Status(byte status)
        {
            if (status == 1)
            {
                Serial_OpenMode_Print.Checked = true;
                return "打印模式 开启成功";
            }
            else
            {
                Serial_CloseMode_Print.Checked = true;
                return "打印模式 已关闭";
            }
        }
        private string RadioButton_AutoSendModel_Status(byte status)
        {
            if (status == 1)
            {
                Serial_OpenMode_AutoSend.Checked = true;
                return "打印模式 开启成功";
            }
            else
            {
                Serial_CloseMode_AutoSend.Checked = true;
                return "打印模式 已关闭";
            }
        }

        //委托处理事件
        private void UpdateTextBox(byte[] text)
        {
            string Status = "";
            bool CheckStatus = CheckFrame(text);
            if(CheckStatus == false)
            {
                Test_Read_Data(text);

                Status = "帧校验错误";
            }
            else
            {
                switch (text[1])
                {
                    case 0x10:                  //写地址
                        Status = "地址 写入成功";
                        break;
                    case 0x20:                  //读地址
                        Serial_Addr.Text = text[2].ToString();
                        Status = "地址 读出成功";
                        break;
                    case 0x30:                  //开启/关闭 低功耗模式
                        Status = RadioButton_LowerPowerModel_Status(text[2]);
                        break;
                    case 0x40:                  //读设备状态
                        RadioButton_AutoSendModel_Status(text[2]);
                        Serial_Addr.Text = text[3].ToString();
                        RadioButton_LowerPowerModel_Status(text[4]);
                        Serial_Interval.Text = ((text[5] << 8) + text[6]).ToString();
                        Status = "设备状态 读出成功";
                        break;
                    case 0x50:                  //读ID
                        Serial_ID.Text = text[2].ToString("D2") + text[3].ToString("D2") + text[4].ToString("D2") + text[5].ToString("D2");
                        Status = "ID 读出成功";
                        break;
                    case 0x60:                  //写ID
                        Status = "ID 写入成功";
                        break;
                    case 0x71:                  //写系数
                        Status = "系数写入成功";
                        break;
                    case 0x80:                  //开启/关闭 打印模式
                        Status = RadioButton_PrintModel_Status(text[2]);
                        break;
                    case 0x91:                  //读系数
                        for (int i = 0; i < 10; i++)
                        {
                            for (int j = 0; j < 4; j++)
                            {
                                WriteCoeff.Rows[i].Cells[2 + j].Value = ((text[(i * 4 + j) * 2 + 3] << 8) + text[(i * 4 + j) * 2 + 4]).ToString();
                            }
                        }
                        Status = "系数读出成功";
                        break;
                    case 0x92:                  //开启/关闭 主动上传模式
                        Status = RadioButton_AutoSendModel_Status(text[2]);
                        break;
                    case 0xA0:                  //修改上传时间间隔
                        Status = "修改时间间隔 成功";
                        break;
                }
            }

            Label_Status.Text = Status;
        }

        // 发送函数 加CRC校验发送
        private void Serial_SendData(byte[] Tx, int Length)
        {
            byte[] Buff = new byte[Length + 2];
            UInt16 CheckSum = 0;
            Tx.CopyTo(Buff, 0);
            CheckSum = myclass_crc.CRC16(Buff, Length);

            Buff[Length] = (byte)(CheckSum & 0x00ff);
            Buff[Length + 1] = (byte)(CheckSum >> 8);

            Serial1.Write(Buff, 0, Length + 2);
        }

        //当串口参数（控件）改变后，调用
        private void Serial_Param_Changed(object sender, EventArgs e)
        {
            if (Serial1.IsOpen)
            {
                Serial_Open();
                Serial_Status();
            }
        }

        //打开串口
        private void Button_OpenPort_Click(object sender, EventArgs e)
        {
            if (Serial1.IsOpen)
            {
                Serial1.Close();
            }
            else
            {
                Serial_Open();
            }
            Serial_Status();
        }
        
        //检查按键是否为数字和 空格 和回车
        private void KeyPress_IsDigit(object sender, KeyPressEventArgs e)
        {
            if(!char.IsDigit( e.KeyChar )&& (e.KeyChar != '\b') && (e.KeyChar != '\r'))
            {
                //阻止从键盘输入键
                e.Handled = true;
                MessageBox.Show("请输入数字！");
            }
            else if (e.KeyChar == '\r')
            {
                System.Windows.Forms.SendKeys.Send(" ");
                e.Handled = true;
            }
        }

        //导管状态（Radio 控件） 变换点击时 调用
        private void Serial_Radio_Click(object sender, MouseEventArgs e)
        {
            int     Length = 0;
            string  Node = "";
            RadioButton Radio = new RadioButton();
            byte[] Tx = new byte[] { 0x00, 0x00, 0x00, 0x00};

            if (sender.Equals(Serial_CloseMode_LowPower))
            {
                Node = "您确定关闭低功耗模式吗？";
                Radio = Serial_CloseMode_LowPower;
                Tx[1] = 0x30;
                Tx[2] = 0x00;
                Length = 3;
            }
            else if (sender.Equals(Serial_OpenMode_LowPower))
            {
                Node = "您确定开启低功耗模式？";
                Radio = Serial_OpenMode_LowPower;
                Tx[1] = 0x30;
                Tx[2] = 0x01;
                Length = 3;
            }
            else if (sender.Equals(Serial_CloseMode_Print))
            {
                Node = "您确定关闭打印模式吗？";
                Radio = Serial_CloseMode_Print;
                Tx[1] = 0x80;
                Tx[2] = 0x00;
                Length = 3;
            }
            else if (sender.Equals(Serial_OpenMode_Print))
            {
                if(Serial_OpenMode_LowPower.Checked == true)
                {
                    MessageBox.Show("请先关闭低功耗模式！");
                    return;
                }
                else
                {
                    Node = "您确定开启打印模式？";
                    Radio = Serial_OpenMode_Print;
                    Tx[1] = 0x80;
                    Tx[2] = 0x01;
                    Length = 3;
                }
            }
            else if (sender.Equals(Serial_CloseMode_AutoSend))
            {
                Node = "您确定关闭主动上传模式吗？";
                Radio = Serial_CloseMode_AutoSend;
                Tx[1] = 0x92;
                Tx[2] = 0x00;
                Tx[3] = 0x00;
                Length = 4;
            }
            else if (sender.Equals(Serial_OpenMode_AutoSend))
            {
                if (Serial_OpenMode_LowPower.Checked == false)
                {
                    MessageBox.Show("请先开启低功耗模式！");
                    return;
                }
                else
                {
                    Node = "您确定开启主动上传模式？";
                    Radio = Serial_OpenMode_AutoSend;
                    Tx[1] = 0x92;
                    Tx[2] = 0x00;
                    Tx[3] = 0x01;
                    Length = 4;
                }
            }
            DialogResult r = MessageBox.Show(Node, "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (r == DialogResult.OK)
            {
                Radio.Checked = true;

                Serial_SendData(Tx, Length);
            }
        }

        private void Serial_Write_Interval_Click(object sender, EventArgs e)
        {
            string Text = Serial_Interval.Text;
            if(Text.Length <= 0)
            {
                MessageBox.Show("文本框不能为空！");
            }
            else
            {
                int Interval = int.Parse(Text);
                if(Interval >= 300 && Interval <= 0xffff)
                {
                    byte[] Tx = new byte[] { 0x00, 0xA0, 0x00, 0x00 };

                    Tx[2] = (byte)(Interval >> 8);
                    Tx[3] = (byte)(Interval & 0xff);
                    Serial_SendData(Tx, Tx.Length);
                }
                else
                {
                    MessageBox.Show("时间间隔范围为（300~65535 s）");
                }
            }
        }
        //发送读导管配置命令
        private void Serial_ReadStatus_Work_Click(object sender, EventArgs e)
        {
            byte[] Tx = new byte[] { 0x00, 0x40};

            Serial_SendData(Tx, Tx.Length);
        }
        //发送读ID命令
        private void Serial_ReadID_Click(object sender, EventArgs e)
        {
            byte[] Tx = new byte[] { 0x00, 0x50 };

            Serial_SendData(Tx, Tx.Length);
        }
        //发送写ID 命令
        private void Serial_WriteID_Click(object sender, EventArgs e)
        {
            string Text = Serial_ID.Text;
            if (Text.Length != 8)
            {
                MessageBox.Show("请输入正确的 ID 号！");
            }
            else
            {
                byte[] Temp = String_Hex_Exchange.Str2Byte(Text);
                byte[] Tx = new byte[] { 0x00, 0x60, 0x00, 0x00, 0x00, 0x00 };
                Temp.CopyTo(Tx, 2);
                
                Serial_SendData(Tx, Tx.Length);
            }
        }
        //发送写地址命令
        private void Serial_WriteAddr_Click(object sender, EventArgs e)
        {

            string Text = Serial_Addr.Text;
            if (Text.Length <= 0 || Text.Length > 3)
            {
                MessageBox.Show("请输入正确的地址(0~255)！");
            }
            else
            {
                int Addr = int.Parse(Text);
                if (Addr <= 255)
                {
                    byte[] Tx = new byte[] { 0x00, 0x10, (byte)Addr };
                    Serial_SendData(Tx, Tx.Length);
                }
                else
                {
                    MessageBox.Show("请输入正确的地址(0~255)！");
                }
            }
        }
        //发送读地址命令
        private void Serial_ReadAddr_Click(object sender, EventArgs e)
        {
            byte[] Tx = new byte[] { 0x00, 0x20 };

            Serial_SendData(Tx, Tx.Length);
        }
        
        // 写系数点击窗口 事件处理
        private void WriteCoeff_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            //获取当前点击的行
            if ((WriteCoeff.CurrentCell is DataGridViewButtonCell || WriteCoeff.CurrentCell is DataGridViewCheckBoxCell )&& e.RowIndex > -1)
            {
                if (!Serial1.IsOpen)
                {
                    MessageBox.Show("请先打开串口");
                    return;
                }
                //获取当前被点击的单元格
                DataGridViewButtonCell btnCell = WriteCoeff.CurrentCell as DataGridViewButtonCell;
                byte[] DataBuff = new byte[83];
                string WriteData = "";
                for(int i = 0; i < 10; i++)
                {
                    for(int j = 0; j < 4; j++)
                    {
                        string str_tmp = WriteCoeff.Rows[i].Cells[2 + j].Value.ToString();
                        if(str_tmp.Length > 0)
                        {
                            int data_tmp = int.Parse(str_tmp);
                            if (data_tmp <= 0xffff)
                            {
                                WriteData += str_tmp + "\t";
                                DataBuff[(i * 4 + j) * 2 + 3] = (byte)(data_tmp >> 8);
                                DataBuff[(i * 4 + j) * 2 + 4] = (byte)(data_tmp & 0x00ff);
                            }
                        }
                    }
                    WriteData += "\r\n";
                }

                switch ((DataGirdViewControls)e.ColumnIndex)
                {
                    case DataGirdViewControls.All_Select:

                            int len = WriteCoeff.RowCount;
                            DataGridViewCheckBoxCell chbCell = WriteCoeff.CurrentCell as DataGridViewCheckBoxCell;
                            bool Selected = chbCell.Selected;
                            for (int i = 0; i < len; i++)
                            {
                                if (Selected == true)
                                {
                                    WriteCoeff.Rows[i].Cells[0].Value = true;
                                }
                                else
                                {
                                    WriteCoeff.Rows[i].Cells[0].Value = false;
                                }
                            }
                    break;

                    case DataGirdViewControls.ReadCoeff:
                            byte[] Tx = new byte[] { 0x00, 0x91, 0x80 };
                            Serial_SendData(Tx, Tx.Length);
                        break;

                    case DataGirdViewControls.WriteCoeff:
                            DataBuff[0] = 0x00;
                            DataBuff[1] = 0x71;
                            DataBuff[2] = 80;

                            Serial_SendData(DataBuff, DataBuff.Length);
                        break;

                    case DataGirdViewControls.SaveCoeff:
                        SaveFileDialog sfd = new SaveFileDialog();
                        sfd.Filter = "系数文件(*.txt)|*.txt|所有文件|*.*";
                        sfd.ValidateNames = true;
                        sfd.CheckPathExists = true;
                        sfd.CreatePrompt = true;
                        sfd.OverwritePrompt = true;
                        if (sfd.ShowDialog() == DialogResult.OK)
                        {
                            string strFileName = sfd.FileName;
                            //其他代码

                            try
                            {
                                Stream stream = File.OpenWrite(strFileName);

                                using (StreamWriter writer = new StreamWriter(stream))
                                {
                                    writer.Write(WriteData);
                                }
                            }
                            catch (IOException ex)
                            {
                                MessageBox.Show(ex.Message, "Simple Editor", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            }
                        }
                        break;

                    case DataGirdViewControls.LoadCoeff:
                        OpenFileDialog ofd = new OpenFileDialog();
                        ofd.Filter = "系数文件(*.txt)|*.txt|所有文件|*.*";
                        ofd.ValidateNames = true;
                        ofd.CheckPathExists = true;
                        ofd.CheckFileExists = true;
                        if (ofd.ShowDialog() == DialogResult.OK)
                        {
                            string strFileName = ofd.FileName;

                            try
                            {
                                Stream stream = File.OpenRead(strFileName);

                                using (StreamReader reader = new StreamReader(stream))
                                {
                                    string fileData = reader.ReadToEnd();
                                    fileData = fileData.Replace("\r\n","");
                                    string[] ceoffData = fileData.Split(new char[] {'\r', '\n', '\t'});

                                    for (int i = 0; i < 10; i++)
                                    {
                                        for (int j = 0; j < 4; j++)
                                        {
                                            WriteCoeff.Rows[i].Cells[2 + j].Value = ceoffData[i*4 + j];
                                        }
                                    }
                                }
                            }
                            catch (IOException ex)
                            {
                                MessageBox.Show(ex.Message, "Simple Editor", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                            }
                        }
                        break;

                    default:
                    break;
                }
            }
        }

        // 写系数单元格生效后 事件处理
        private void WriteCoeff_CellValidated(object sender, DataGridViewCellEventArgs e)
        {
            int col = e.ColumnIndex;
            int row = e.RowIndex;
            if (col > 1)
            {
                string str_tmp = WriteCoeff.Rows[row].Cells[col].Value.ToString();
                if (str_tmp.Length == 0)
                    WriteCoeff.Rows[row].Cells[col].Value = '0';
            }
        }

        //初始化串口列表
        private void Init_COM_Port_List()
        {
            string[] Serial_List = SerialPort.GetPortNames();
            Serial_COM.Items.Clear();
            if (Serial_List.Count() > 0)
            {
                Array.Sort(Serial_List);                                //数组排序
                Serial_COM.Items.AddRange(Serial_List);
            }
            else
            {
                Serial_COM.Items.Add("请接入串口设备！");
            }
            Serial_COM.SelectedIndex = 0;
            //if(Serial_COM.Items.Count == 0)
            //{
            //    Serial_COM.Items.AddRange(new object[] {
            //    "COM1",
            //    "COM2",
            //    "COM3",
            //    "COM4",
            //    "COM5",
            //    "COM6",
            //    "COM7",
            //    "COM8",
            //    "COM9",
            //    "COM10",
            //    "COM11",
            //    "COM12",
            //    "COM13",
            //    "COM14",
            //    "COM15",
            //    "COM16"});
            //}
        }

        //初始化写入系数 DataGridView 控件
        private void Init_Write_Coeff()
        {
            //DataGridView 新增新行
            WriteCoeff.ColumnHeadersHeight = 30;
            WriteCoeff.RowTemplate.Height = 35;
            for (int index = 0; index < 9;)
            {
                index = WriteCoeff.Rows.Add();
                WriteCoeff.Rows[index].DefaultCellStyle.BackColor = (index % 2 == 1) ? Color.DarkGray : Color.White;
                WriteCoeff.Rows[index].DefaultCellStyle.SelectionBackColor = Color.Green;
                WriteCoeff.Rows[index].DefaultCellStyle.SelectionForeColor = Color.Black;
                WriteCoeff.Rows[index].Cells[0].Value = true;
                WriteCoeff.Rows[index].Cells[1].Value = index + 1;
                WriteCoeff.Rows[index].Cells[1].ReadOnly = true;
                WriteCoeff.Rows[index].Cells[2].Value = "0";
                WriteCoeff.Rows[index].Cells[3].Value = "0";
                WriteCoeff.Rows[index].Cells[4].Value = "0";
                WriteCoeff.Rows[index].Cells[5].Value = "0";
            }
            DataGridViewRow Row = new DataGridViewRow();
            DataGridViewCheckBoxCell CheckBoxCell = new DataGridViewCheckBoxCell();
            CheckBoxCell.Value = true;
            Row.Cells.Add(CheckBoxCell);
            DataGridViewTextBoxCell TextBoxCell1 = new DataGridViewTextBoxCell();
            TextBoxCell1.Value = "";
            Row.Cells.Add(TextBoxCell1);
            DataGridViewButtonCell ButtonCell2 = new DataGridViewButtonCell();
            ButtonCell2.Value = "读系数";
            Row.Cells.Add(ButtonCell2);
            DataGridViewButtonCell ButtonCell3 = new DataGridViewButtonCell();
            ButtonCell3.Value = "写系数";
            Row.Cells.Add(ButtonCell3);
            DataGridViewButtonCell ButtonCell4 = new DataGridViewButtonCell();
            ButtonCell4.Value = "保存";
            Row.Cells.Add(ButtonCell4);
            DataGridViewButtonCell ButtonCell5 = new DataGridViewButtonCell();
            ButtonCell5.Value = "导入";
            Row.Cells.Add(ButtonCell5);
            WriteCoeff.Rows.Add(Row);
            WriteCoeff.Rows[10].Cells[1].ReadOnly = true;
            int Height = WriteCoeff.Size.Height - WriteCoeff.Rows[0].Height * 10 - WriteCoeff.ColumnHeadersHeight;
            WriteCoeff.Rows[10].Height = Height;
            //this.WriteCoeff.DataSource = DataGirdViewBindData;
        }

        //增加按键控制
        private void WriteCoeff_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            //检测是被表示的控件还是DataGridViewTextBoxEditingControl
            if (e.Control is DataGridViewTextBoxEditingControl)
            {
                DataGridView dgv = (DataGridView)sender;

                //取得被表示的控件
                DataGridViewTextBoxEditingControl tb = (DataGridViewTextBoxEditingControl)e.Control;

                //事件处理器删除
                tb.KeyPress -= new KeyPressEventHandler(KeyPress_IsDigit);
                //检测对应列
                //if (dgv.CurrentCell.OwningColumn.Name == "单价")
                if (dgv.CurrentCell.ColumnIndex > 1)
                {
                    // KeyPress事件处理器追加
                    tb.KeyPress += new KeyPressEventHandler(KeyPress_IsDigit);
                }
            }
        }

        //重写按键处理程序，禁止DataGridView 的enter 输入
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Enter && WriteCoeff.Focused)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        // usb消息定义
        public const int WM_DEVICE_CHANGE = 0x219;
        public const int DBT_DEVICEARRIVAL = 0x8000;
        public const int DBT_DEVICE_REMOVE_COMPLETE = 0x8004;
        public const UInt32 DBT_DEVTYP_PORT = 0x00000003;
        /// 检测USB串口的拔插
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_DEVICE_CHANGE)        // 捕获USB设备的拔出消息WM_DEVICECHANGE
            {
                switch (m.WParam.ToInt32())
                {
                    case DBT_DEVICE_REMOVE_COMPLETE:    // USB拔出 
                    case DBT_DEVICEARRIVAL:             // USB插入获取对应串口名称
                        Serial_Status();

                        Init_COM_Port_List();
                        break;
                    case WM_DEVICE_CHANGE:
                        break;
                }
            }
            base.WndProc(ref m);
        }

        private RadioButton Check_Radio_Selected(GroupBox groupBox)
        {
            int select_num = 0, control_num = groupBox.Controls.Count;
            RadioButton return_radio_obj = null, tmp_radio_obj;
            for (int i = 0; i < control_num; i++)
            {
                tmp_radio_obj = groupBox.Controls[i] as RadioButton;
                if (tmp_radio_obj != null && tmp_radio_obj.Checked)
                {
                    select_num++;
                    return_radio_obj = tmp_radio_obj;
                }
            }
            if(select_num == 1)
            {
                return return_radio_obj;
            }
            else
            {
                return null;
            }
        }

        private void Test_ClearAll_Click(object sender, EventArgs e)
        {
            RadioButton select_radio = Check_Radio_Selected(groupBox_Test);
            if(select_radio != null)
            {
                select_radio.Checked = false;
            }

            Test_ReceiveView.Text = "";
            Test_Cmd.Text = "";
        }

        // 发送指令  开启某一层测试
        private void Test_Radio_Click(object sender, MouseEventArgs e)
        {
            if (Serial1.IsOpen == false)
            {
                MessageBox.Show("请打开串口！");
            }
            else
            {
                RadioButton Radio = (RadioButton) sender;
                string Tx = Radio.Text;
                string Node = "确定开启" + Tx + "?";
                Tx = Tx.ToLower() + "\r\n";

                DialogResult r = MessageBox.Show(Node, "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (r == DialogResult.OK)
                {
                    Radio.Checked = true;

                    Write_To_TextBox(Tx, Test_ReceiveView, 0);
                    Serial1.Write(Tx);
                }
            }
        }

        //一个接口，用来在TextBox 控件中分格式写入数据
        private void Write_To_TextBox(string str, TextBox textBox, int Display_Style)
        {
            if(Display_Style == 0)
                textBox.Text += str + "\r\n";
        }

        private void Test_Read_Data(byte[] arr)
        {
            if(Serial_OpenMode_Print.Checked == true)
            {
                string Recv_Data = GB2312.GetString(arr);

                Write_To_TextBox(Recv_Data, Test_ReceiveView, 0);
            }
        }

        private void Serial_RecvText_TextChanged(object sender, EventArgs e)
        {
            Test_ReceiveView.SelectionStart = Test_ReceiveView.Text.Length;
            Test_ReceiveView.ScrollToCaret();
        }

        //关闭低功耗模式后，打开扩展窗口
        private void Serial_CloseMode_LowPower_CheckedChanged(object sender, EventArgs e)
        {
            if (Serial_CloseMode_LowPower.Checked == false)
            {
                if(this.Width > 800)
                {
                    this.Width -= 420;
                }
            }
            else
            {
                if (this.Width < 800)
                {
                    this.Width += 420;
                }
            }
        }
    }
}
